package com.sc.nft.admin.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.sc.nft.admin.request.*;
import com.sc.nft.annotation.SysMemberLogin;
import com.sc.nft.dao.UserCreatorInfoDao;
import com.sc.nft.entity.CdkActivityInfo;
import com.sc.nft.entity.UserCreatorInfo;
import com.sc.nft.entity.req.EcologyCastGasRequest;
import com.sc.nft.entity.vo.AddCdkActivityVO;
import com.sc.nft.entity.vo.CdkExchangeRecordVO;
import com.sc.nft.entity.vo.PageCdkVO;
import com.sc.nft.enums.RedemptionCodeRuleEnum;
import com.sc.nft.enums.RedisKeyEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.pool.SysMemberPool;
import com.sc.nft.pool.UserPool;
import com.sc.nft.service.CDKProductService;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.sup.PageRequest;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.concurrent.TimeUnit;

import static com.sc.nft.enums.ProductCdkTypeEnum.EQUITY_PROPS_PRODUCT;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/admin/cdkActivity")
@Api(tags = "后台cdk活动管理")
public class CdkActivityController {

    private final CDKProductService cdkProductService;
    private final Redisson redisson;
    private final UserCreatorInfoDao userCreatorInfoDao;
    @PostMapping(value = "/addCdkActivity", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "添加CDK活动", notes = "添加CDK活动", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result addCdkActivity(@Valid @RequestBody AddCdkActivityRequest request) {
        request.getEcologyCastGas().checkEcologyCastGas();
        if(RedemptionCodeRuleEnum.CUSTOM.getCode() == request.getRedemptionCodeRule().getCode()){
            Assert.isFalse(ObjectUtil.isNull(request.getRedemptionTotal()),()->new GlobalRunTimeException("兑换码生成总量不能为空"));
            Assert.isFalse(ObjectUtil.isNull(request.getUserUseLimit()),()->new GlobalRunTimeException("用户使用上限不能为空"));
        }

        UserCreatorInfo dao = userCreatorInfoDao.getById(request.getDaoId());
        Assert.notNull(dao, ()->new GlobalRunTimeException("dao不存在"));
        Assert.isTrue(dao.getStatus() == 1, ()->new GlobalRunTimeException("请先申请成为DAO"));
        CdkActivityInfo cdkActivityInfo = BeanUtil.copyProperties(request, CdkActivityInfo.class);
        cdkActivityInfo.setRemainingQuantity(cdkActivityInfo.getRedemptionTotal());
        DateTime beginTime = DateUtil.parse(request.getBeginTime(), "yyyy-MM-dd HH:mm:ss");
        DateTime endTime = DateUtil.parse(request.getEndTime(), "yyyy-MM-dd HH:mm:ss");
        Assert.isFalse(beginTime.isAfter(endTime),()->new GlobalRunTimeException("结束时间不能大于开始时间"));
        EcologyCastGasRequest ecologyCastGas = request.getEcologyCastGas();
        cdkActivityInfo.setGasConf(ecologyCastGas.getGasConf());
        if (ecologyCastGas.getGasConf()){
            cdkActivityInfo.setConsumeCost(ecologyCastGas.getConsumeCost());
            cdkActivityInfo.setConsumeType(ecologyCastGas.getConsumeType());
        }

        //根据生成规则
        if(RedemptionCodeRuleEnum.CUSTOM.getCode() == request.getRedemptionCodeRule().getCode()){
            if(EQUITY_PROPS_PRODUCT.getCode() != request.getProductType().getCode()){
                throw new GlobalRunTimeException("请选择正确的权益道具");
            }
            //创建的时候生成兑换码，并加入到库存中
            String key = RedisKeyEnum.GENERATE_CDK_LOCK.getKey() + SysMemberPool.getMember().getId();
            RLock lock = redisson.getLock(key);
            try {
                boolean res = lock.tryLock(1,TimeUnit.SECONDS);
                if (res) {
                    cdkProductService.createCustomCDK(cdkActivityInfo,request.getProductId(),request.getRedemptionTotal());
                }else {
                    return Result.fail(ErrorCode.LATER_TRY);
                }
            } catch (InterruptedException e) {
                return Result.fail("CDK生成中，请勿重复提交!");
            } finally {
                lock.unlock();
            }
            return Result.success();
        }else {
            cdkActivityInfo.insert();
            return Result.success();
        }
    }

    @PostMapping(value = "/updateCdkActivity", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "修改CDK活动", notes = "修改CDK活动", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result updateCdkActivity(@Valid @RequestBody UpdateCdkActivityRequest request) {
        request.getEcologyCastGas().checkEcologyCastGas();
        cdkProductService.updateCdkActivity(request.getId(),
                request.getActivityTitle(),
                request.getActivityDescription(),
                request.getBeginTime(),
                request.getEndTime(),
                request.getProductType(),
                request.getFirstTitle(),
                request.getProductId(),
                request.getEcologyCastGas().getGasConf(),
                request.getEcologyCastGas().getConsumeType(),
                request.getEcologyCastGas().getConsumeCost(),
                request.getDaoId(),request.getRedemptionCodeRule(),request.getRedemptionTotal(),request.getUserUseLimit());
        return Result.success();
    }
    @PostMapping(value = "/deleteCdkActivity", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "删除CDK活动", notes = "删除CDK活动", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result deleteCdkActivity(@Valid @RequestBody IdRequest request) {
        cdkProductService.deleteCdkActivity(request.getId());
        return Result.success();
    }


    @PostMapping(value = "/getPageCdkActivity", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取CDK活动列表", notes = "获取CDK活动列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<AddCdkActivityVO> getCdkActivityList(@Valid @RequestBody AdminCdkPageRequest request) {
        return PageResult.success(cdkProductService.getCdkActivityList(request.getPageNo(), request.getPageSize(),request.getName()));
    }


    @PostMapping(value = "/getPageCdk", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取CDK列表", notes = "获取CDK列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<PageCdkVO> getPageCdk(@Valid @RequestBody PageCdkRequest request) {
        return PageResult.success(cdkProductService.getPageCdk(request.getCdkActivityId(),request.getCdk(),request.getIsUse(),request.getIsExpired(),request.getPageNo(), request.getPageSize()));
    }


    @PostMapping(value = "/generateCDK", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "生成CDK", notes = "生成CDK", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result generateCDK(@Valid @RequestBody GenerateCDKRequest request) {
        String key = RedisKeyEnum.GENERATE_CDK_LOCK.getKey() + request.getActivityId();
        RLock lock = redisson.getLock(key);
        try {
            boolean res = lock.tryLock(1,TimeUnit.SECONDS);
            if (res) {
                cdkProductService.generateCDK(request.getActivityId(),request.getGenerateNum());
            }else {
                return Result.fail(ErrorCode.LATER_TRY);
            }
        } catch (InterruptedException e) {
            return Result.fail("CDK生成中，请勿重复提交!");
        } finally {
            lock.unlock();
        }

        return Result.success();
    }

    @PostMapping(value = "/cdkExchangeRecord", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "cdk兑换记录", notes = "cdk兑换记录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<CdkExchangeRecordVO> cdkExchangeRecord(@Valid @RequestBody CdkExchangeRecordRequest request) {
        return PageResult.success(cdkProductService.adminCdkExchangeRecord(request.getUserTel(),request.getCdk(),request.getPageNo(), request.getPageSize(),request.getCdkActivityId()));
    }

}
